# -*- py-indent-offset: 4 -*-
# -*- tab-width: 8 -*-
# -*- indent-tabs-mode: nil -*-
"""Opens an interactive dialog where the user can enter and execute python commande in the sniff enironment."""
from etgui import *
import regsub
import CmdNo,string,sys
from PageLayout import *
import traceback,time
if sys.path[0]!='':
	sys.path.insert(0,'')

def ShowFileDialog(how=eFDRead,filename=None,title="Select a file"):
	wd=None
	if filename and gSystem.DirName(filename):
#		wd=gSystem.WorkingDirectory()
		gSystem.ChangeDirectory(gSystem.DirName(filename))
	result=SelectFile(title,how)
#	if wd is not None:
#		gSystem.ChangeDirectory(wd)
	return result



class RunPython:
	def __init__(self,model,infield,outfield):
		self.model=model
		self.infield=infield
		self.outfield=outfield
		self.output=[]
		self.context={}
		self.history=''
		self.file=''
		self.model.SetValue("Input",'')
		self.originput=''
		self.SetInput('')
	def SetFile(self,file):
		if file and gSystem.DirName(file):
			gSystem.ChangeDirectory(gSystem.DirName(file))
		self.file=file
	def GetCmd(self):
		cmd=self.model.GetValue("Input")
		cmd=regsub.gsub('\r','',cmd)
		if cmd and cmd[:-1]!='\n':
			cmd=cmd+'\n'
		return cmd
	def GetInput(self):
		return self.model.GetValue("Input")
	def do_import(self,name, globals={}, locals={}, fromlist=[]):
		if not self.loaded.has_key(name) and globals is self.context:
			if name=='Register': # treat the register module special
				print "@rRegister Reset!@x"
				print "\t@bKeymap@x:          Type C-g or Esc g to reset the current Keymap."
				print "\t@bSyntaxHighlight@x: Load another file in the editor to see the change"
				import RegisterInit
				RegisterInit.ReInit(1)
			else:
				self.loaded[name]=name
			try:
				reload(sys.modules[name])
			except:
				pass
		return self.old_import(name,globals,locals,fromlist)
	def Exec(self):
		import __builtin__
		self.context={'__name__':'__main__'}
		self.loaded={}
		for n in (__name__,'sys','KeyHandler','RegisterImpl','RegisterInit','vcs'):
			self.loaded[n]=n
		cmd=self.GetCmd()
		self.ClearOutput()
		stdout=sys.stdout
		stderr=sys.stderr
		sys.stdout=self
		sys.stderr=self
		self.time=time.time()
		try:
			self.old_import=__builtin__.__import__
			__builtin__.__import__=self.do_import
			try:
#               try:
#                   exec '_=' + cmd in self.context,self.context
#                   if self.context['_'] is not None:
#                       print "_=",self.context['_']
#               except:
#                   self.ClearOutput()
#                   self.context={}
				exec cmd in self.context,self.context
			except:
				self.write('@r@B') # get der output
				traceback.print_exc()
		finally:
			self.flush()
			sys.stdout=stdout
			sys.stderr=stderr
			__builtin__.__import__=self.old_import
	def ClearOutput(self):
		self.output=[]
		self.outfield.SetString("")
	def SavedChanges(self):
		if self.GetInput()!=self.originput:
			file=self.file
			if not file:
				file="?Untitled?"
			result=ShowAlert(eAlertCaution,"Save changes to @b%s@b?"%file)
			if result==CmdNo.cIdYes:
				return self.Save()
			elif result==CmdNo.cIdCancel:
				return 0
		return 1
		
	def SetInput(self,input):
		self.history=self.GetInput()
		self.originput=input
		self.model.SetValue("Input",input)
		self.context={}
		self.ClearOutput()
	def Clear(self):
		if not self.SavedChanges():
			return
		self.SetInput('')
		self.file=''
	def UndoClear(self):
		self.SetInput(self.history)
		self.file=''
	def Reload(self):
		if not self.SavedChanges():
			return
		if self.file:
			self.LoadFile(self.file)
		else:
			self.Load()
	def Load(self):
		if not self.SavedChanges():
			return
		file=ShowFileDialog(eFDRead,self.file,"Python Input File")
		self.LoadFile(file)
	def LoadFile(self,file):
		if file:
			try:
				input=open(file).read()
			except IOError,details:
				ShowAlert(eAlertStop,"Error reading file @B%s@B:\n%s" %(file,details[1]))
				return
			self.SetInput(input)
			self.SetFile(file)
			#self.Exec()
	def Save(self):
		if self.file:
			return self.SaveFile(self.file)
		else:
			return self.SaveAs()
	def SaveAs(self):
		file=ShowFileDialog(eFDWrite,self.file,"Pot Output File")
		return self.SaveFile(file)
	def SaveFile(self,file):
		if file:
			try:
				fp=open(file,'w')
				fp.write(self.GetCmd())
				fp.close()
				self.SetFile(file)
				self.originput=self.GetInput()
				return 1
			except IOError,details:
				ShowAlert(eAlertStop,"Error writing file @B%s@B:\n%s" %(file,details[1]))
	def write(self,data):
		self.output.append(data)
		if '\n' in data and (time.time()-self.time)>0.1:
			self.flush()
	def flush(self):
		self.outfield.SetString(string.join(self.output,''))
		self.time=time.time()
def MakeDialog():
	model=PotGuiModel()
	outfield=MultilineTextItem("",-1,gFixedFont)
	infield=TextView()
	evaluator=RunPython(model,infield,outfield)
	panel=VSplitExpander(
		align=eVObjHExpand|eVObjVExpand,
		items=[
			HBox(
				align=eVObjVBase|eVObjHEqual|eVObjHExpand,
				items= [
					ActionButton("Run",default=1,action=evaluator.Exec),
					ActionButton("New",default=1,action=evaluator.Clear),
					ActionButton("Load...",default=1,action=evaluator.Load),
					ActionButton("Reload",default=1,action=evaluator.Reload),
					ActionButton("Save",default=1,action=evaluator.Save),
					ActionButton("Save As...",default=1,action=evaluator.SaveAs),
				]
			),
			PotGuiTextView("Input",infield,Point(100)),
			VSplitter(
				items=[
					Scroller(outfield)
				]
			)
		]
	)

	dialog=PotGuiDialog(
		model,
		panel,
		"Python",
		eWinDefault
	)
	return dialog
gDialog=None
def Show():
	global gDialog
	if not gDialog:
		gDialog=MakeDialog()
	gDialog.ShowUnderMouse()


